from mxit.commands import *
from mxit.handles import *

class HandleManager:

    def __init__(self, con):
        self.handlers = []
        self.con = con
        self.add_handler(0, fallback_handler, pass_filter)
        self.add_cmd_handler(20, ack_handler, Client.MESSAGE, Client.PRESENCE, Client.MOOD, Client.LOGOUT, Client.PROFILE, Client.PING)
        self.add_cmd_handler(1, pass_handler, Client.MESSAGE, Client.PRESENCE, Client.MOOD, Client.LOGOUT, Client.PROFILE, Client.PING)
        self.add_cmd_handler(10, login_handler, Client.LOGIN)
        self.add_cmd_handler(10, profile_req_handler, Client.PROFILE_REQUEST)
        self.add_cmd_handler(10, profile_handler, Client.PROFILE)
        self.add_handler(10, echo_handler, command_filter(Client.MESSAGE))
        self.add_handler(10, pirror_handler, command_filter(Client.PRESENCE))
        self.add_handler(10, mirror_handler, command_filter(Client.MOOD))
        self.add_handler(10, chatter_handler, command_filter(Client.MESSAGE))
        self.add_handler(10, room_handler, command_filter(Client.MESSAGE))
        
    def add_handler(self, priority, handler, *filters):
        self.handlers.append((priority, filters, handler))
        self.handlers.sort(reverse=True)
            
    def add_cmd_handler(self, priority, handler, *commands):
        self.add_handler(priority, handler, command_filter(*commands))
        
    def handle(self, command, data):
        con.reset_ping(); # yay!
        for priority, filters, handler in self.handlers:
            cont = False
            for filter in filters:
                if not filter(self.con, command, data):
                    cont = True
            if cont:
                continue
            if handler(self.con, command, data):
                break
        
def command_filter(*commands):
    return lambda con, cmd, data: cmd in commands

def pass_filter(con, cmd, data):
    return True

def fallback_handler(con, cmd, data):
    con.send_response(cmd, 99, 'Not implemented yet')
    return True
    
def pass_handler(con, cmd, data):
    return True

def ack_handler(con, cmd, data):
    con.send_response(cmd, 0)
    return False
    
def login_handler(con, cmd, data):
    con.s_login()
    return True
    
def profile_handler(con, cmd, data):
    pin, name, private, birthdate, gender, p = data
    user = con.user
    user.name = name
    user.private = PrivateNumber.byid(private)
    user.birthdate = birthdate
    user.gender = Gender.byid(gender)
    return False
    
def profile_req_handler(con, cmd, data):
    #name, private_id, birthdate, gender_id, q
    user = con.user    
    con.s(cmd, [[user.name, user.private.id, user.birthdate, user.gender.id, '']])
    return True

def echo_handler(con, cmd, data):
    jid, message, type = data[:3]
    user = get_user(con, jid)
    
    if user == con.userlist.echo:
        con.s_msg(user, message, type=BuddyType.byid(int(type)))
      
def chatter_handler(con, cmd, data):
    jid, message, type = data[:3]
    user = get_user(con, jid)
    if user == con.userlist.chatter:
        ms = message.split()
        if ms[0] == 'create':
            name = ms[1]
            room = con.create_room(name, user)
            room.participants.append(con.userlist.chatter2)
            con.s_room_invite(room)
        
        #con.s_msg(user, message, type=BuddyType.byid(int(type)))

def room_handler(con, cmd, data):
    jid, message, type = data[:3]
    user = get_user(con, jid)
    if user and user.type == BuddyType.ROOM:
        if message.startswith('.list'):
            con.s_room_list(user)
    
def pirror_handler(con, cmd, data):
    presence, msg = data
    
    echo = con.userlist.echo
    echo.presence = Presence.byid(int(presence))
    contact = con.user.get_contact(echo)
    if contact:
        con.s_presence(contact)
    
def mirror_handler(con, cmd, data):
    mood, = data
    
    echo = con.userlist.echo
    echo.mood = Mood.byid(int(mood))
    contact = con.user.get_contact(echo)
    if contact:
        con.s_presence(contact)
        
def get_user(con, jid):
    if jid in con.userlist:
        return con.userlist[jid]
    else:
        return None
    